#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Description:
import re

import constants
from utils.logger import Logger
from utils.ssh import SSHClient

log = Logger()


def parse_disk_info(ipaddr):
    """
    获取当前环境的磁盘信息
    :param ipaddr: ip地址
    :return:
    """
    ssh = SSHClient(ip=ipaddr)
    # 解析 qdisk 设备映射
    qdisk_output = ssh.exec_cmd(command=constants.SYSTEM_LL_QDISK)
    nvme_output = ssh.exec_cmd(command=constants.SYSTEM_NVME_LIST)
    pcie_output = ssh.exec_cmd(command=constants.SYSTEM_SLOT_PATH)

    qdisk_pattern = re.compile(r'(?P<qdisk_path>/dev/qdisk/\S+) -> \.\./(?P<device>nvme\d+n\d+)')
    qdisk_map = {f'/dev/{m.group("device")}': m.group('qdisk_path') for m in qdisk_pattern.finditer(qdisk_output)}

    # 解析 NVMe 设备信息：SN 部分
    nvme_sn_pattern = re.compile(r'^(?P<device_path>/dev/nvme\d+n\d+)\s+(?P<sn>\S+)', re.MULTILINE)
    nvme_sn_info = {m.group('device_path'): m.group('sn') for m in nvme_sn_pattern.finditer(nvme_output)}

    # 解析 NVMe 设备信息：容量部分
    nvme_capacity_pattern = re.compile(r'^(?P<device_path>/dev/nvme\d+n\d+).*?\s+(?P<capacity>[\d\.]+\s*TB)\s*/',
                                       re.MULTILINE)
    nvme_capacity_info = {m.group('device_path'): m.group('capacity').replace(' ', '') for m in
                          nvme_capacity_pattern.finditer(nvme_output)}

    # 合并 SN 和容量信息
    nvme_info = {}
    for device_path in nvme_sn_info:
        if device_path in nvme_capacity_info:
            nvme_info[device_path] = {
                'sn': nvme_sn_info[device_path],
                'capacity': nvme_capacity_info[device_path]
            }

    # 解析 PCIe 路径信息，仅提取 pcie_path 部分，例如 "0000:89:00"
    pcie_pattern = re.compile(
        r'(?P<device>nvme\d+) -> .*(?P<pcie_path>0000:[\da-fA-F]{2}:[\da-fA-F]{2})\.0/nvme/'
    )
    pcie_path_map = {
        f'/dev/{m.group("device")}n1': m.group("pcie_path")  # 这里在 nvmeX 后面加上 "n1"
        for m in pcie_pattern.finditer(pcie_output)
    }

    # 组合数据到最终结果
    result = []

    for device_path, qdisk_path in qdisk_map.items():

        if device_path in nvme_info and device_path in pcie_path_map:
            result.append({
                'qdisk_path': qdisk_path,
                'device_path': device_path,
                'sn': nvme_info[device_path]['sn'],
                'capacity': nvme_info[device_path]['capacity'],
                'pcie_path': pcie_path_map[device_path],
                'slot_id': get_slot_id(ipaddr, pcie_path_map[device_path]),
                'sign': 'UNUSED'
            })
    return result


def get_slot_id(ip, pci_address) -> str:
    ssh = SSHClient(ip=ip)
    result = ssh.exec_cmd(command=constants.SYSTEM_LSPCI_SLOT.format(pci_address))
    match = re.search(r"/slots/(\d+)/", result)
    slot_id = ""
    if match:
        slot_id = match.group(1)

    return slot_id


def get_disk_status(qdisk_path: str):
    """
    获取磁盘的状态
    :param qdisk_path: udev路径
    :return: 磁盘状态（USED 或 UNUSED）
    """

    for disk in constants.local_data.disk_info:
        if disk["qdisk_path"] == qdisk_path:
            return disk["sign"]
    log.error(f"未找到磁盘: {qdisk_path}")
    return None


def set_disk_status(qdisk_list: list, status: str):
    """
    修改一组磁盘的状态
    :param qdisk_list: 需要修改状态的磁盘路径列表
    :param status: 新的状态（USED 或 UNUSED）
    :return:
    """
    # 遍历数组
    for qdisk_path in qdisk_list:
        found = False
        for disk in constants.local_data.disk_info:
            if disk["qdisk_path"] == qdisk_path:
                # 修改匹配到的磁盘状态
                disk["sign"] = status
                found = True
                break
        if not found:
            # 打印未匹配到的盘
            log.error(f"未匹配到盘: {qdisk_path}")


def get_disk_list(status) -> list:
    """
    获取盘，返回qdisk_list
    :param status: 需要的状态（USED 或 UNUSED）
    :return:
    """
    disk_list = []
    for disk in constants.local_data.disk_info:
        if disk.get("sign") == status:
            disk_list.append(disk["qdisk_path"])
    log.info(f"当前{status}状态的盘有{disk_list}")
    return disk_list


def create_partition_disk():
    """
    磁盘分区工具，根据环境的盘，来构建failgroup需要的盘数
    :return:
    """
    pass


def clean__partition_disk():
    """
    清理磁盘分区，重新构建disk info
    :return:
    """
    pass


def get_disk_capacity(used_disk):
    """
    获取容量
    :param used_disk:
    :return:
    """
